#!/usr/bin/env python

#       gtkdllib.py
#       2008 Mirat Can Bayrak <horselogy@pardus-nx8220>
#       
import urllib , os.path , gtk
from urlparse import urlparse

class http_object:
    def __init__(   self,
                    url,                        # url of remote file.
                    folder = './',              # folder is used for creating local name of url file
                    file_name = None ,               # if given foo/index.html's local_name will be foo/name
                    del_local_if_exist = True,  # if local mirror of url file is exits remove it.
                    blocksize = 4096 ,          # number of bytes that will be retrieved when get_block function called.
                ):
        self.url = url
        self.accessible = True
        # get a urllibobject
        try:
            self.url_obj = urllib.urlopen(url)
        except IOError:
            self.accessible = False
        if self.accessible:
            # read content_length from url_obj's headers
            self.content_length = int(self.url_obj.headers.get('content-length')) 
            # create a local file name  (folder + filename on server)
            if file_name:
                self.file_name = file_name
            else:
                self.file_name = os.path.basename(urllib.url2pathname(self.url))
            self.file_name
            self.local_name = os.path.join(folder,self.file_name)
            # completed bytes of file
            self.completed = 0
            # number of bytes that will be retrieved when get_block function called.
            self.block_size = blocksize
            # del local mirror of remote folder if exits and user wanted to delete it
            if del_local_if_exist and os.path.exists(self.local_name): os.unlink(self.local_name)
    def get_block(self):
        """
            Gets a block from remote file
        """
        local_file = file(self.local_name,'a')
        if self.content_length - self.completed > self.block_size:
            local_file.write(self.url_obj.read(self.block_size))
            self.completed += self.block_size
            return True # we got block
        else:
            blocksize = self.url_obj.read(self.content_length-self.completed)
            local_file.write(blocksize)
            local_file.close()
            return False # download completed
class downloader:
    def __init__(self,source_url,destination_folder = "./",file_name = None,progress_bar=None,progress_bar_display_type = "in_kb"):
        self.source_url = source_url
        self.destination_folder = destination_folder
        self.progress_bar = progress_bar
        self.progress_bar_display_type = progress_bar_display_type
        self.file_name = file_name
        self.file = http_object(self.source_url,self.destination_folder,self.file_name)   
        self.finish_info = "Download Completed"
        if not self.file.accessible : self.progress_bar.set_text('file is not accessible')
    def stop(self,widget=None,data=None):
        self.downloading = False
        self.file.__init__(self.source_url,self.destination_folder)
        self.completed = 0
        self.finish_info = "Download Cancelled by User"
    def start(self,widget =None ,data=None):
        self.downloading = True
        self.finish_info = "Download Completed"
        self.download()
    def download(self):
        while self.downloading == True:
            self.downloading = self.file.get_block()  
            while gtk.events_pending(): gtk.main_iteration()
            self.progress_bar.set_fraction(float(self.file.completed)/float(self.file.content_length))
            if self.progress_bar_display_type == 'in_b':
                self.progress_bar.set_text(str(self.file.completed) + 'b / ' + str(self.file.content_length) + ' b')
            elif self.progress_bar_display_type == 'in_kb':
                self.progress_bar.set_text(str(self.file.completed / 1024)+ 'kb / ' + str(self.file.content_length / 1024) +' kb')
            elif self.progress_bar_display_type == 'in_mb':
                self.progress_bar.set_text(str(self.file.completed / 1048576)+ 'mb / ' + str(self.file.content_length / 1048576) +' mb')
        self.progress_bar.set_text(self.finish_info)
        self.progress_bar.set_fraction(1)
